package com.wrupple.muba.base.client.module.services.logic;

import java.util.HashMap;
import java.util.Map;

import com.google.gwt.http.client.URL;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceHistoryMapper;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.wrupple.muba.common.domain.DesktopPlace;

@Singleton
public class DesktopPlaceHistoryMapperImpl implements PlaceHistoryMapper {
	
	

	@Inject
	public DesktopPlaceHistoryMapperImpl() {
		super();
	}

	@Override
	public Place getPlace(String token) {
		String activity = parseApplicationItemId(token);
		DesktopPlace matchingChild = new DesktopPlace();
		matchingChild.setActivity(activity);
		addParamentersToPlace(matchingChild,token);
		return matchingChild;
	}


	@Override
	public String getToken(Place place) {
		assert place instanceof DesktopPlace : "Desktop Place History Management supports only instances of ApplicationItem";
		DesktopPlace item = (DesktopPlace) place;
		String token = generateToken(item.getActivity(), item.getProperties());
		return token;
	}



	private void addParamentersToPlace(DesktopPlace matchingChild,String token) {
		Map<String, String> parameters = getUrlParameters(token);
		matchingChild.setProperties(parameters);
	}

	private  Map<String, String> getUrlParameters(String url){
	    Map<String, String> params = new HashMap<String, String>();
	    String[] urlParts = url.split("\\?");
	    if (urlParts.length > 1) {
	        String query = urlParts[1];
	        String[] paramString = query.split("&");
	        for (String param : paramString) {
	            String pair[] = param.split("=");
	            String key = URL.decode(pair[0]);
	            String value = URL.decode(pair[1]);
	            params.put(key, value);
	        }
	    }
	    return params;
	}

	private String parseApplicationItemId(String hash) {
		String historyToken = hash;
		if (historyToken == null) {
			return "";
		} else {
			int index = historyToken.indexOf('?');
			if (index != -1) {
				return historyToken.substring(1, index);
			} else {
				return historyToken;
			}
		}
	}

	private String generateToken(String itemId, Map<String, String> paramMap) {
		return "!"+itemId + "?" + getParametersAsQueryString(new HashMap<String, String>(paramMap));
	}

	private String getParametersAsQueryString(Map<String, String> paramMap) {
		paramMap.remove(DesktopPlace.IMAGE_PARAMETER);
		paramMap.remove(DesktopPlace.LABEL_PARAMETER);
		StringBuilder query = new StringBuilder();
		int count = 0;
		String value = null;
		for (String k : paramMap.keySet()) {
			if (count > 0) {
				query.append('&');
			}
			value = paramMap.get(k);
			if (value != null) {
				query.append(k);
				query.append('=');
				query.append(URL.encodeQueryString(value));
				count++;
			}
		}
		return query.toString();
	}

}
